import qs from 'qs'
import sm from './Sm2Utils'

const SELECT_PROP = {
  label: 'label',
  value: 'value'
}

const TREE_PROP = {
  label: 'label',
  value: 'value',
  children: 'children'
}

const _findNode = (val, treeData, prop) => {
  if (!val || !treeData) return

  prop = Object.assign({}, TREE_PROP, prop)

  for (let i = 0; i < treeData.length; i++) {
    let node = treeData[i]
    if (val === node[prop.value]) {
      return node
    }

    let childNode = node[prop.children]
    if (childNode) {
      node = _findNode(val, childNode, prop)
      if (node) {
        return node
      }
    }
  }
}

const _transDict = (val, dictData, prop) => {
  if (!val || !dictData) {
    return val
  }

  prop = Object.assign({}, SELECT_PROP, prop)

  for (let i in dictData) {
    let _dictData = dictData[i]
    if (val === _dictData[prop.value]) {
      return _dictData[prop.label]
    }
  }
}

const _transTree = (val, treeData, prop) => {
  let node = _findNode(val, treeData, prop)
  if (node) {
    prop = Object.assign({}, TREE_PROP, prop)

    return node[prop.label]
  }
}

const _arrayToJson = (arr) => {
  if (!Array.isArray(arr)) {
    return {}
  }

  let res = {}
  arr.map((item, index) => {
    Object.keys(item).map(key => {
      res['row_' + index + '_' + key] = item[key]
    })
  })

  return res
}

const _stringToPower = (str) => {
  let power = {
    n: 0,
    f: ''
  }

  if (str === null || str === undefined || str === '') {
    return power
  }

  if (/^\d+(\.(\d{0,2})?)?$/.test(str)) {
    power.f = str
    power.n = Number(str)
  } else {
    let f = parseFloat(str)
    if (!isNaN(f)) {
      f = f.toFixed(2)
      power.f = f
      power.n = Number(f)
    }
  }

  return power
}

const _trim = (str) => {
  return (str || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '')
}

const _hasPermission = (path, menu) => {
  if (!path || !menu) return

  for (let i = 0; i < menu.length; i++) {
    let node = menu[i]
    if (node && node.raw && node.raw.value && path === node.raw.value) {
      return true
    }

    let childNode = node.children
    if (childNode) {
      node = _hasPermission(path, childNode)
      if (node) {
        return true
      }
    }
  }

  return false
}

const _formatParam = (param) => {
  return qs.stringify(param)
}

const _clearFormData = (formData) => {
  for (let field in formData) {
    formData[field] = null
  }
}

const _genTableData = (tableData) => {
  return Object.assign({}, {
    loading: false,
    deleting: false,
    param: {},
    currentPage: 1,
    pageSize: 10,
    total: 0,
    items: [],
    selection: [],
    currentItem: null
  }, tableData)
}

const _yearArray = (n) => {
  let years = []
  n = n || 5
  var y = new Date().getFullYear()
  for (let i = 0; i < n; i++) {
    years.push(y - i)
  }
  return years
}

const _rowspanTable = (items, fields) => {
  if (!Array.isArray(items)) return
  if (!Array.isArray(fields) && (typeof fields) !== 'string') return

  if ((typeof fields) === 'string') {
    fields = [fields]
  }

  fields.forEach(field => {
    items.reduce((prev, cur) => {
      if (cur[field] === prev[field]) {
        cur[field + '_rowspan'] = 0
        typeof prev[field + '_rowspan'] === 'number'
        ? prev[field + '_rowspan'] ++
        : prev[field + '_rowspan'] = 2
        return prev
      } else {
        cur[field + '_rowspan'] = 1
        return cur
      }
    })
  })

  return items
}

const _get_uuid = () => {
  var s = []
  var hexDigits = "0123456789abcdef"
  for (var i = 0; i < 36; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
  }
  s[14] = "4"
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
  s[8] = s[13] = s[18] = s[23] = "-"
  var uuid = s.join("")
  return uuid
}

const _generateRequestToken = () => {
  let token = {
    token: _get_uuid(),
    timestamp: new Date().getTime()
  }
  token.sign = sm.Sm3Utils.encrypt(token.timestamp+','+token.token)
  return token
}

export default {
  // 查找树节点
  findNode (val, treeData, prop) {
    return _findNode(val, treeData, prop)
  },
  // 翻译数据字典
  transDict (val, dictData, prop) {
    return _transDict(val, dictData, prop)
  },
  // 翻译树
  transTree (val, treeData, prop) {
    return _transTree(val, treeData, prop)
  },
  // 数组->对象
  arrayToJson (arr) {
    return _arrayToJson(arr)
  },
  // 字符串 -> 电量
  stringToPower (str) {
    return _stringToPower(str)
  },
  trim (str) {
    return _trim(str)
  },
  hasPermission (path, menu) {
    return _hasPermission(path, menu)
  },
  formatParam (param) {
    return _formatParam(param)
  },
  clearFormData (formData) {
    return _clearFormData(formData)
  },
  genTableData (tableData) {
    return _genTableData(tableData)
  },
  yearArray (n) {
    return _yearArray(n)
  },
  rowspanTable (items, fields) {
    return _rowspanTable(items, fields)
  },
  uuid () {
    return _get_uuid()
  },
  generateRequestToken () {
    return _generateRequestToken()
  }
}
